home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 18 / develop 18 code / OSA Sample / Sources / SimpliFace.cp < prev    next >
Encoding:
Text File  |  1994-01-28  |  22.9 KB  |  998 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SimpliFace.cp
  3.  
  4.     Contains:    A simple scriptable application class.
  5.  
  6.     Developed by:    
  7.         
  8.         Paul G Smith (commstalk hq & Full Moon Software, Inc)
  9.         
  10.         you can leave messages at (UK): 0727 844232; (US): 408 253 7199
  11.         BUT I prefer to be contacted by e-mail
  12.         AppleLink:     SMITH.PG
  13.         Internet:     SMITH.PG@applelink.apple.com
  14.         
  15.         "SimpliFace" Sample code to accompany develop article
  16.         on techniques for embedding scripts in applications.
  17.  
  18.     Important note on Segmentation strategy: 
  19.         There is none. This program is compiled with -model far 
  20.         (MPW 32-bit everything). If you convert it to Think C++
  21.         you'll need to segment it.
  22.  
  23. */
  24.  
  25.  
  26. #ifndef __SimpliFace__
  27. #include <SimpliFace.h>
  28. #endif
  29.  
  30. #ifndef __SimpliFaceCOMMON__
  31. #include "SimpliFaceCommon.h"
  32. #endif
  33.  
  34. #ifndef __APPLICATIONCOMMON__
  35. #include "ApplicationCommon.h"
  36. #endif
  37.  
  38. #ifndef __STDIO__
  39. #include <StdIO.h>
  40. #endif
  41.  
  42. #ifndef __MENUS__
  43. #include <Menus.h>
  44. #endif
  45. #ifndef __FONTS__
  46. #include <Fonts.h>
  47. #endif
  48. #ifndef __EVENTS__
  49. #include <Events.h>
  50. #endif
  51. #ifndef __WINDOWS__
  52. #include <Windows.h>
  53. #endif
  54. #ifndef __DIALOGS__
  55. #include <Dialogs.h>
  56. #endif
  57. #ifndef __QUICKDRAW__
  58. #include <Quickdraw.h>
  59. #endif
  60. #ifndef __MEMORY__
  61. #include <Memory.h>
  62. #endif
  63. #ifndef __RESOURCES__
  64. #include <Resources.h>
  65. #endif
  66. #ifndef __PACKAGES__
  67. #include <Packages.h>
  68. #endif
  69. #ifndef __TOOLUTILS__
  70. #include <ToolUtils.h>
  71. #endif
  72. #ifndef __FILES__
  73. #include <Files.h>
  74. #endif
  75. #ifndef __STANDARDFILE__
  76. #include <StandardFile.h>
  77. #endif
  78. #ifndef __GESTALTEQU__
  79. #include <GestaltEqu.h>
  80. #endif
  81. #ifndef __SYSEQU__
  82. #include <SysEqu.h>
  83. #endif
  84. #ifndef __PLSTRINGFUNCS__
  85. #include <PLStringFuncs.h>
  86. #endif
  87.  
  88. #ifndef __AEOBJECTS__
  89. #include <AEObjects.h>
  90. #endif
  91.  
  92. #ifndef __AEOBJECTPACKING__
  93. #include <AEPackObject.h>
  94. #endif
  95.  
  96. #ifndef __AERegistry__
  97. #include <AERegistry.h>
  98. #endif
  99. #ifndef __ASREGISTRY__
  100. #include <ASRegistry.h>
  101. #endif
  102.  
  103. #ifndef __AEOMTOKENS__
  104. #include "ObjModelTokens.h"
  105. #endif
  106. #ifndef __AEOMEVENTS__
  107. #include "ObjModelEvents.h"
  108. #endif
  109.  
  110. #ifndef __SCRIPTUTILS__
  111. #include "ScriptUtils.h"
  112. #endif
  113.  
  114. #ifndef __WINDOWOBJ__
  115. #include "WindowObj.h"
  116. #endif
  117.  
  118. extern "C" {
  119. #include "AEBuild.h"
  120. #include "AEBuildGlobals.h"
  121. #include "AEPrint.h"
  122. }
  123. #include "AEBuildErrMsgs.h"
  124.  
  125.  
  126. #include "DebugTrace.h"
  127.  
  128.  
  129. #define        kMinStackSize     40000
  130. #define        kMinHeapSize     150000
  131.  
  132. #define        kWNEsleepTicks    10
  133.  
  134. #define     kSaveGlobVars    false
  135.  
  136.  
  137. /* some globals we need for the static methods */
  138.  
  139. TSimpliFace*    gSimpliFace = NULL;
  140. Boolean         gDone = false;
  141. Boolean         gQuit = false;
  142.  
  143. int main()
  144. {
  145.     gSimpliFace = new TSimpliFace(Ptr(&qd));
  146.     
  147.     AEObjectInit();
  148.  
  149.     // Start our main event loop running.
  150.     while (!gQuit && gSimpliFace) 
  151.     {
  152.         gSimpliFace->EventLoop();
  153.         gQuit = true;
  154.     }
  155.     if (gSimpliFace)
  156.     {
  157.         delete gSimpliFace;
  158.         gSimpliFace = NULL;
  159.     }
  160.     
  161.     // We always return a value, like good little ANSI worshippers
  162.     return 0;
  163. }
  164.  
  165. /**********************************************************************
  166. **  SimpliFace static methods
  167. ***********************************************************************/
  168.  
  169. #define optionKeyCode     58
  170. static Boolean isKeyDown(long keyCode);
  171. static void AlertUser(short errResID, short errCode);
  172.  
  173. /**********************************************************************
  174. ** isKeyDown
  175. ***********************************************************************/
  176.  
  177. static Boolean isKeyDown(long keyCode)
  178. {
  179.     KeyMap keys;
  180.     Byte *keysBytes;
  181.     
  182.     GetKeys(keys);
  183.     
  184.     keysBytes = (Byte *)keys;
  185.  
  186.     return((keysBytes[keyCode/8] & (1 << keyCode % 8)) != 0);
  187. }
  188.  
  189. /**********************************************************************
  190. **  AlertUser
  191. ***********************************************************************/
  192.  
  193. void AlertUser(short errResID, short errCode)
  194. {
  195.     Str255 message;
  196.  
  197.     GetIndString(message, errResID, errCode);
  198.     #if qDebug
  199.     if (message[0] == 0)
  200.     {
  201.         DebugStr((ConstStr255Param)"\pProgram error: could not get error string.");
  202.         return;
  203.     }
  204.     #endif
  205.     ParamText(message, (ConstStr255Param)"\p", (ConstStr255Param)"\p", (ConstStr255Param)"\p");
  206.     Alert(rUserAlert, NULL);
  207. }
  208.  
  209.  
  210. /**********************************************************************
  211. **  CheckGestaltOSA: return false if we can't load
  212. ***********************************************************************/
  213.  
  214. Boolean CheckGestaltOSA(void)
  215. {
  216.     OSErr    err = 0;
  217.     long    ascrAttr = 0;
  218.     long    ascrVers = 0;
  219.     char    ascrVersStr[24];
  220.     
  221.     err = Gestalt('ascr', &ascrAttr);
  222.     if (!err)
  223.     {
  224.         err = Gestalt('ascv', &ascrVers);
  225.         sprintf(ascrVersStr, "%.8lx", ascrVers);
  226.         printf("AppleScript version %.2s.%.1s.%.1s   [$%s]\n", 
  227.                 &ascrVersStr[0], &ascrVersStr[2], &ascrVersStr[3], ascrVersStr);
  228.     }
  229.     else
  230.         printf("AppleScript not present\n");
  231.     
  232.     return (err == 0);
  233. }
  234.  
  235. /**********************************************************************
  236. ** PUBLIC Constructor
  237. ***********************************************************************/
  238.  
  239. TSimpliFace::TSimpliFace(Ptr qdPtr) : TApplication(qdPtr)
  240. {    
  241.     InstallWriteLnHook();    // debug assistance, so printf() works for us
  242.     ForceDebug();
  243.     
  244.     if (CheckGestaltOSA())
  245.     {
  246.         // read menus into menu bar
  247.     
  248.         Handle menuBar = GetNewMBar(rMenuBar);
  249.         // install menus
  250.         SetMenuBar(menuBar);
  251.     
  252.         // add DA names to Apple menu
  253.         AddResMenu(GetMHandle(mApple),'DRVR');
  254.         DrawMenuBar();
  255.     
  256.         // create empty mouse region
  257.         fMouseRgn = NewRgn();
  258.         // make sure we have a valid cursor region
  259.         AdjustCursor();
  260.     }
  261.     else
  262.         TApplication::BigBadError(kApplicationErrStrings,eNeedAS); // if not, alert & quit
  263. }
  264.  
  265. TSimpliFace::~TSimpliFace()
  266. {
  267.     StopScriptAdministrator();             // do it here in case we have a forced exit
  268.     DisposHandle(Handle(fMouseRgn));
  269. }
  270.  
  271. /**********************************************************************
  272. ** PUBLIC SetUp/Cleanup
  273. ***********************************************************************/
  274.  
  275. void TSimpliFace::SetUp()
  276. {    // Run before event loop starts
  277.     OSAError         err = 0;
  278.     
  279.     err = StartScriptAdministrator();
  280.     
  281. }
  282.  
  283. void TSimpliFace::CleanUp()
  284. {
  285.     StopScriptAdministrator();
  286. }
  287.  
  288. /**********************************************************************
  289. ** PUBLIC SleepVal
  290. ***********************************************************************/
  291.  
  292. unsigned long TSimpliFace::SleepVal()
  293. {
  294.     return kWNEsleepTicks;        // how long to sleep in WaitNextEvent
  295. }
  296.  
  297.  
  298. /**********************************************************************
  299. ** PUBLIC DoIdle
  300. ***********************************************************************/
  301.  
  302. void TSimpliFace::DoIdle()
  303. {
  304. }
  305.  
  306.  
  307. Boolean TSimpliFace::HandleGoAway (AEDesc *target, WindowPtr tWind)
  308. {
  309.     Boolean                wasHandled = false;
  310.     OSErr                err = 0;
  311.     AppleEvent            event, reply;
  312.     ProcessSerialNumber    aSelfPSN = gSelfPSN;
  313.     CStr255                aeOtherParams =    "'savo':'ask '";
  314.     
  315.     err = AEBuildAppleEvent(kAECoreSuite, kAEClose,
  316.                             typeProcessSerialNumber, &aSelfPSN,
  317.                             sizeof(aSelfPSN), kAutoGenerateReturnID,
  318.                             kAnyTransactionID, &event,
  319.                             (char*)aeOtherParams);
  320.     if (!err)
  321.         err = AEPutParamDesc(&event, keyDirectObject, target);
  322.     
  323.     if (!err)
  324.     {
  325.         err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  326.                          kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  327.         AEDisposeDesc(&event);
  328.         wasHandled = (err == noErr);
  329.     }
  330.     
  331.     return wasHandled;
  332. }
  333.  
  334.  
  335. Boolean TSimpliFace::HandleContentClick (AEDesc *target, 
  336.                                          WindowPtr tWind, EventRecord& theEvent)
  337. {
  338.     Boolean                wasHandled = false;
  339.     Point                clickPt = theEvent.where;
  340.     ControlHandle        whichControl = NULL;
  341.     
  342.     GlobalToLocal(&clickPt);
  343.     
  344.     short controlPart = FindControl(clickPt, tWind, &whichControl);
  345.     
  346.     if (!controlPart || 
  347.         (controlPart && whichControl && TrackControl(whichControl, clickPt, NULL)))
  348.     {
  349.         OSErr                err = 0;
  350.         AppleEvent            event, reply;
  351.         ProcessSerialNumber    aSelfPSN = gSelfPSN;
  352.         CStr255                theHPos, theVPos;
  353.         NumToString(theEvent.where.h, theHPos);
  354.         NumToString(theEvent.where.v, theVPos);
  355.         CStr255                aeOtherParams =    "'PEVK':'EMOU',"
  356.                                             "'data':[“" + theHPos + "”,"
  357.                                                     "“" + theVPos + "”]";
  358.         err = AEBuildAppleEvent(kSignature, kAESystemEvent,
  359.                                 typeProcessSerialNumber, &aSelfPSN,
  360.                                 sizeof(aSelfPSN), kAutoGenerateReturnID,
  361.                                 kAnyTransactionID, &event,
  362.                                 (char*)aeOtherParams);
  363.         if (!err)
  364.             err = AEPutParamDesc(&event, keyDirectObject, target);
  365.         
  366.         if (!err)
  367.         {
  368.             err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  369.                              kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  370.             AEDisposeDesc(&event);
  371.             wasHandled = (err == noErr);
  372.         }
  373.     }
  374.     return wasHandled;
  375. }
  376.  
  377.  
  378. Boolean TSimpliFace::HandleMenuCommand(AEDesc *target, 
  379.                                         short menuNum, short itemNum)
  380. {
  381.     Boolean            wasHandled = false;
  382.     MenuHandle        thisMenu = GetMHandle(menuNum);
  383.     CStr255            menuName, itemName;
  384.     
  385.     if (thisMenu && *thisMenu)
  386.     {
  387.         GetItem(thisMenu, itemNum, itemName);
  388.         menuName = ((*thisMenu)->menuData);
  389.     }
  390.     else
  391.     {
  392.         menuName = "";
  393.         itemName = "";
  394.     }
  395.     
  396.     if (menuName != "" && itemName != "")
  397.     {
  398.         OSErr                err = 0;
  399.         AppleEvent            event, reply;
  400.         ProcessSerialNumber    aSelfPSN = gSelfPSN;
  401.         CStr255                aeOtherParams =    "'PEVK':'EMEN',"
  402.                                             "'data':[“" + menuName + "”,"
  403.                                                     "“" + itemName + "”]";
  404.         err = AEBuildAppleEvent(kSignature, kAESystemEvent,
  405.                                 typeProcessSerialNumber, &aSelfPSN,
  406.                                 sizeof(aSelfPSN), kAutoGenerateReturnID,
  407.                                 kAnyTransactionID, &event,
  408.                                 (char*)aeOtherParams);
  409.         if (!err)
  410.             err = AEPutParamDesc(&event, keyDirectObject, target);
  411.         
  412.         if (!err)
  413.         {
  414.             err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  415.                              kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  416.             AEDisposeDesc(&event);
  417.             wasHandled = (err == noErr);
  418.         }
  419.     }
  420.     return wasHandled;
  421. }
  422.  
  423.  
  424. Boolean TSimpliFace::HandleMouseDown(AEDesc *target, EventRecord& theEvent)
  425. {
  426.     Boolean        wasHandled = false;
  427.     long         mResult;
  428.     short         partCode;
  429.     WindowPtr     tWind;
  430.  
  431.     // gotta watch those object field dereferences
  432.     partCode = FindWindow(theEvent.where, &tWind);
  433.     switch (partCode)
  434.       {
  435.         case inMenuBar :
  436.             AdjustMenus();
  437.             mResult = MenuSelect(theEvent.where);
  438.             if (mResult != 0)
  439.             {
  440.                 wasHandled = HandleMenuCommand(target, HiWord(mResult), LoWord(mResult));
  441.                 if (!wasHandled)    // hack! we are anticipating EventLoop():
  442.                 {                    // this is to avoid calling MenuSelect() twice
  443.                     DoMenuCommand(HiWord(mResult),LoWord(mResult));
  444.                     wasHandled = true;    
  445.                 }
  446.             }
  447.             break;
  448.         case inGoAway :
  449.             wasHandled = HandleGoAway(target, tWind);                    
  450.             break;
  451.         case inContent :
  452.             // If window is not in front, make it so
  453.             if ( tWind != FrontWindow() )
  454.                   SelectWindow(fWhichWindow);
  455.             else
  456.                 wasHandled = HandleContentClick(target, tWind, theEvent);                    
  457.             break;
  458.       }    
  459.     
  460.     return wasHandled;
  461. }
  462.  
  463.  
  464. Boolean TSimpliFace::HandleKeyDown(AEDesc *target, EventRecord& theEvent)
  465. {
  466.     Boolean        wasHandled = false;
  467.     char         key = (char) (fTheEvent.message & charCodeMask);
  468.     
  469.     if ((fTheEvent.modifiers & cmdKey) && (fTheEvent.what == keyDown))
  470.     {
  471.         // only do command keys if we are not autokeying
  472.         AdjustMenus();                    // make sure menus are up to date
  473.         long mResult = MenuKey(key);
  474.         if (mResult != 0)                // if it wasn't a menu key, pass it through
  475.             wasHandled = HandleMenuCommand(target, HiWord(mResult), LoWord(mResult));
  476.     }
  477.     else
  478.     {
  479.         OSErr                err = 0;
  480.         AppleEvent            event, reply;
  481.         ProcessSerialNumber    aSelfPSN = gSelfPSN;
  482.         CStr255                theKeyPressed;
  483.         theKeyPressed[1] = key;
  484.         theKeyPressed[0] = 1;
  485.         CStr255                aeOtherParams =    "'PEVK':'EKEY',"
  486.                                             "'data':“" + theKeyPressed + "”";
  487.         err = AEBuildAppleEvent(kSignature, kAESystemEvent,
  488.                                 typeProcessSerialNumber, &aSelfPSN,
  489.                                 sizeof(aSelfPSN), kAutoGenerateReturnID,
  490.                                 kAnyTransactionID, &event,
  491.                                 (char*)aeOtherParams);
  492.         if (!err)
  493.             err = AEPutParamDesc(&event, keyDirectObject, target);
  494.         
  495.         if (!err)
  496.         {
  497.             err = AESend(&event, &reply, kAENoReply+kAEAlwaysInteract, 
  498.                              kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
  499.             AEDisposeDesc(&event);
  500.             wasHandled = (err == noErr);
  501.         }
  502.     }
  503.     
  504.     return wasHandled;
  505. }
  506.  
  507.  
  508. Boolean TSimpliFace::HandleEvent(EventRecord& theEvent, Boolean& /*pass*/)
  509. {
  510.     Boolean        wasHandled = false;
  511.     AEDesc         target;
  512.     
  513.     InitAEDescs(&target, kEndOfList);
  514.  
  515.     switch (theEvent.what)
  516.     {
  517.         case mouseDown :
  518.             if (GetTargetObjectSpecifier(theEvent, &target) == noErr)
  519.                 wasHandled = HandleMouseDown(&target, theEvent);
  520.             break;
  521.         case keyDown :
  522.         case autoKey :
  523.             if (GetTargetObjectSpecifier(theEvent, &target) == noErr)
  524.                 wasHandled = HandleKeyDown(&target, theEvent);
  525.             break;
  526.     } // end switch (fTheEvent.what)
  527.  
  528.     DisposeAEDescs(&target, kEndOfList);
  529.     
  530.     return wasHandled;
  531. }
  532.  
  533.  
  534. OSErr TSimpliFace::CollectAETEs(short /*languageCode*/, AEDesc& resultDesc)
  535. {
  536.     OSErr        err = noErr;
  537.     Handle        aeutH = NULL;
  538.     
  539.     aeutH = GetResource(typeAETE, 0);
  540.     if (aeutH)
  541.     {
  542.         char hState = HGetState(aeutH);
  543.         HLock(aeutH);
  544.         err = AEPutPtr(&resultDesc, 0, typeAETE, *aeutH, GetHandleSize(aeutH));
  545.         HSetState(aeutH, hState);
  546.     }
  547.     else
  548.         err = -192; /* resNotFound */ 
  549.  
  550.     return err;
  551. }
  552.  
  553.  
  554. /**********************************************************************
  555. ** PUBLIC AdjustMenus
  556. ***********************************************************************/
  557.  
  558. // Enable and disable menus based on the current state. The
  559. // user can only select enabled menu items. We set up all the
  560. // menu items before calling MenuSelect or MenuKey, since
  561. // these are the only times that a menu item can be selected.
  562. // Note that MenuSelect is also the only time the user will
  563. // see menu items. This approach to deciding what enable/
  564. // disable state a menu item has the advantage of
  565. // concentrating all the decision-making in one routine, as
  566. // opposed to being spread throughout the application. Other
  567. // application designs may take a different approach that may
  568. // or may not be as valid. 
  569.  
  570. void ExactAppend(MenuHandle aMenu, Str255 aString)
  571. {
  572.     unsigned char fillString[128];
  573.     /* Since AppendMenu will interpret meta-characters, first append a menu item with    */
  574.     /* no meta-characters, but which has the same length as aString, then set the menu    */
  575.     /* item to astring (SetItem doesn't interpret meta-characters). */
  576.     fillString[0] = aString[0];
  577.     if (aString[0])
  578.         memset(fillString + 1, 'a', aString[0]);
  579.     AppendMenu(aMenu, fillString);
  580.     SetItem(aMenu, CountMItems(aMenu), aString);
  581. }    
  582.     
  583. void TSimpliFace::AdjustMenus(void)
  584. {
  585.     WindowPtr    frontmost;
  586.     MenuHandle    menu;
  587.     Boolean        undo;
  588.     Boolean        cutCopyClear;
  589.     Boolean        paste;
  590.  
  591.     frontmost = FrontWindow();
  592.  
  593.     /* Edit menu */
  594.  
  595.     menu = GetMHandle(mEdit);
  596.     undo = false;
  597.     cutCopyClear = false;
  598.     paste = false;
  599.     if (frontmost != NULL) {
  600.         undo = true;                // all editing is enabled for DA windows 
  601.         cutCopyClear = true;
  602.         paste = true;
  603.     }
  604.  
  605.     if (undo)
  606.         EnableItem(menu, iUndo);
  607.     else
  608.         DisableItem(menu, iUndo);
  609.  
  610.     if (cutCopyClear) {
  611.         EnableItem(menu, iCut);
  612.         EnableItem(menu, iCopy);
  613.         EnableItem(menu, iClear);
  614.     } 
  615.     else {
  616.         DisableItem(menu, iCut);
  617.         DisableItem(menu, iCopy);
  618.         DisableItem(menu, iClear);
  619.     }
  620.     if (paste)
  621.         EnableItem(menu, iPaste);
  622.     else
  623.         DisableItem(menu, iPaste);
  624.  
  625.     /* File Menu */
  626.  
  627.     menu = GetMHandle(mFile);
  628.     if (fWindowObjects.CountElements() > 0)
  629.         EnableItem(menu, iClose);
  630.     else
  631.         DisableItem(menu, iClose);
  632.     EnableItem(menu,iQuit);
  633. }
  634.  
  635. /**********************************************************************
  636. ** PUBLIC AdjustCursor
  637. ***********************************************************************/
  638.  
  639. void TSimpliFace::AdjustCursor()
  640. {
  641.     Boolean        handled = false;
  642.         
  643.     if (!handled)
  644.         SetCursor(&fqd->arrow);
  645. }
  646.  
  647. /**********************************************************************
  648. ** PUBLIC DoMenuCommand
  649. ***********************************************************************/
  650.  
  651. // This is called when an item is chosen from the menu bar (after calling
  652. // MenuSelect or MenuKey). It does the right thing for each command.
  653.  
  654. void TSimpliFace::DoMenuCommand(short menuID, short menuItem)
  655. {
  656.     short        itemHit;
  657.     Str255        daName;
  658.     short        daRefNum;
  659.     WindowPtr    window;
  660.  
  661.     window = FrontWindow();
  662.     switch (menuID) {
  663.         case mApple:
  664.             switch (menuItem) {
  665.                 case iAbout:        // bring up alert for About 
  666.                     itemHit = Alert(rAboutAlert, NULL);
  667.                     break;
  668.                 default:            // all non-About items in this menu are DAs et al 
  669.                     GetItem(GetMHandle(mApple), menuItem, daName);
  670.                     daRefNum = OpenDeskAcc(daName);
  671.                     break;
  672.             }
  673.             break;
  674.  
  675.         case mFile:
  676.             switch (menuItem) {
  677.                 case iQuit:
  678.                     Terminate();
  679.                     break;
  680.                 case iClose:
  681.                     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  682.                     if (theWindObj)
  683.                         theWindObj->CloseObject();
  684.                     else
  685.                         CloseDeskAcc(((WindowPeek) fWhichWindow)->windowKind);
  686.                     break;
  687.             }
  688.             break;
  689.  
  690.         case mEdit:                    // call SystemEdit for DA editing & MultiFinder 
  691.             if (!SystemEdit(menuItem-1))
  692.                 DebugStr((ConstStr255Param)"\pOops.  SystemEdit returned false.");
  693.             break;
  694.         
  695.     }
  696.     HiliteMenu(0);                    // unhighlight what MenuSelect (or MenuKey) hilited 
  697. }
  698.  
  699.  
  700.  
  701. void TSimpliFace::GetThisAppName(CStr255& /*appName*/)
  702. {
  703.     //GetCurrAppName(appName);
  704.  
  705.  
  706. /**********************************************************************
  707. ** PUBLIC Terminate
  708. ***********************************************************************/
  709.  
  710. // Clean up the application and exits. You might want to close all
  711. // of your documents (and ask the user to save them) here.
  712.  
  713. void TSimpliFace::Terminate(void)
  714. {
  715.     ExitLoop();
  716. } // Terminate
  717.  
  718.  
  719. /**********************************************************************
  720. ** PUBLIC StackNeeded/HeapNeeded
  721. ***********************************************************************/
  722.  
  723. long TSimpliFace::StackNeeded()
  724. {
  725.     return kMinStackSize;
  726. }
  727.  
  728. long TSimpliFace::HeapNeeded()
  729. {
  730.     return kMinHeapSize;
  731. }
  732.  
  733.  
  734. /**********************************************************************
  735. ** PUBLIC DoGoAway
  736. ***********************************************************************/
  737.  
  738. void TSimpliFace::DoGoAway(void)
  739. {
  740.     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  741.     if (theWindObj)
  742.     {
  743.         if (TrackGoAway(fWhichWindow, fTheEvent.where)) 
  744.             theWindObj->CloseObject();
  745.     }
  746.     else
  747.         TApplication::DoGoAway();
  748. }
  749.  
  750. /**********************************************************************
  751. ** PUBLIC DoActivateEvt/DoUpdateEvt
  752. ***********************************************************************/
  753.  
  754. void TSimpliFace::DoActivateEvt(void)
  755. {
  756.     // event record contains window ptr
  757.     fWhichWindow = (WindowPtr) fTheEvent.message;
  758.     SetPort(fWhichWindow);
  759.     
  760.     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  761.     if (theWindObj)
  762.         theWindObj->ActivateWindow((fTheEvent.modifiers & activeFlag) != 0);
  763. }
  764.  
  765. void TSimpliFace::DoUpdateEvt(void)
  766. {
  767.     // event record contains window ptr
  768.     fWhichWindow = (WindowPtr) fTheEvent.message;
  769.     SetPort(fWhichWindow);
  770.     
  771.     TWindowObj *theWindObj = (TWindowObj*)(((WindowPeek)fWhichWindow)->refCon);
  772.     if (theWindObj)
  773.         theWindObj->UpdateWindow();
  774. }
  775.  
  776. /**********************************************************************
  777. ** PUBLIC AE Object Model support
  778. ***********************************************************************/
  779.  
  780.  
  781. OSErr TSimpliFace::CountElements(DescType desiredClass, long *result)
  782. {
  783.     OSErr             err = errAEEventNotHandled;
  784.  
  785.     if (desiredClass == cWindow)
  786.     {
  787.         *result = fWindowObjects.CountElements();
  788.         err = 0;
  789.     }    
  790.     return err;
  791. }
  792.  
  793.                                     
  794. OSErr TSimpliFace::GetProperty  (DescType propertyID, DescType wantType, AEDesc *result)
  795. {
  796.     OSErr         err = errAEEventNotHandled;
  797.     CStr255     theName;
  798.     
  799.     switch (propertyID)
  800.     {
  801.     case pName:
  802.         GetCurrAppName(theName);
  803.         err = AECreateDesc(typeChar, (Ptr)&theName[1], theName.Length(), result);
  804.         break;
  805.     case pVersion:
  806.         theName = kVersion;
  807.         err = AECreateDesc(typeChar, (Ptr)&theName[1], theName.Length(), result);
  808.         break;
  809.     case pIsFrontProcess:
  810.         Boolean theBoolean = false;
  811.         ProcessSerialNumber PSN1, PSN2;
  812.         err = GetFrontProcess(&PSN1);
  813.         if (!err)
  814.             err = GetCurrentProcess(&PSN2);
  815.         if (!err)
  816.             err = SameProcess(&PSN1, &PSN2, &theBoolean);
  817.         if (!err)
  818.             err = AECreateDesc(typeBoolean, (Ptr)&theBoolean,
  819.                                 sizeof(theBoolean), result);
  820.         break;
  821.     default:
  822.         err = TScriptableObject::GetProperty(propertyID, wantType, result);
  823.         break;
  824.     }
  825.  
  826.     return err;
  827. }
  828.  
  829.  
  830. OSErr TSimpliFace::SetProperty  (DescType propertyID, const AEDesc *theData)
  831. {
  832.     OSErr                 err = errAEEventNotHandled;
  833.  
  834.     switch (propertyID)
  835.     {
  836.     default:
  837.         err = TScriptableObject::SetProperty(propertyID, theData);
  838.         break;
  839.     }
  840.     
  841.     return err;
  842. }    
  843.  
  844.  
  845. OSErr TSimpliFace::CreateNewElement    (DescType desiredClass,
  846.                                         DescType position,
  847.                                         AEDesc *theData,
  848.                                         AERecord *theProperties,
  849.                                         TScriptableObject *theContainerObj,
  850.                                         TScriptableObject **theNewObj)
  851. {
  852.     OSErr             err = errAEEventNotHandled;
  853.     
  854.     if (desiredClass == cWindow)
  855.     {
  856.         TWindowObj    *newWindowObj = NULL;
  857.         
  858.         if (theProperties)
  859.             newWindowObj = new TWindowObj(theProperties);
  860.         else
  861.         {
  862.             newWindowObj = new TWindowObj();
  863.             if (newWindowObj && theData)
  864.                 newWindowObj->SetProperty(pName, theData);
  865.         }
  866.         if (newWindowObj)
  867.         {
  868.             fWindowObjects.InsertElement((long)newWindowObj);
  869.             *theNewObj = newWindowObj;
  870.             err = 0;
  871.         }
  872.     }
  873.  
  874.     return err;
  875. }    
  876.  
  877.  
  878. OSErr TSimpliFace::ResolveContainer(TScriptableObject **theContainerObj)
  879. {
  880.     OSErr             err = 0;
  881.     
  882.     *theContainerObj = NULL;
  883.  
  884.     return err;
  885. }
  886.  
  887.                                     
  888. OSErr TSimpliFace::ResolveElementByName(DescType desiredClass,
  889.                                         CStr255& nameStr,
  890.                                         TScriptableObject **theResultObj)
  891. {
  892.     OSErr       err = errAEEventNotHandled;
  893.     WindowPtr    theWindow = NULL;
  894.     
  895.     theWindow = WindowNameToWindowPtr((StringPtr)nameStr);
  896.     if (theWindow)
  897.     {    
  898.         // we are making a possibly dangerous assumption: that all windows are ours!
  899.         *theResultObj = (TScriptableObject*)(((WindowPeek)theWindow)->refCon);
  900.         if (*theResultObj != NULL)
  901.             err = 0;
  902.     }
  903.     else
  904.     {
  905.         TWindowObj    *aWindowObj = NULL;
  906.         long        numWindows = fWindowObjects.CountElements();
  907.         CStr255     aName;
  908.         
  909.         while (numWindows > 0)
  910.         {
  911.             aWindowObj = (TWindowObj*)(fWindowObjects.GetElement(numWindows));
  912.             if (aWindowObj)
  913.             {
  914.                 aWindowObj->GetName(aName);
  915.                 if (aName == nameStr)
  916.                 {
  917.                     *theResultObj = aWindowObj;
  918.                     numWindows = 0;
  919.                     err = 0;
  920.                 }
  921.             }
  922.             numWindows--;
  923.         }
  924.     }
  925.     
  926.     return err;
  927. }
  928.  
  929.                                     
  930. OSErr TSimpliFace::ResolveElementByIndex(DescType desiredClass,
  931.                                         short theIndex,
  932.                                         TScriptableObject **theResultObj)
  933. {
  934.     OSErr       err = errAEEventNotHandled;
  935.     WindowPtr    theWindow = NULL;
  936.     CStr255     nameStr = "";
  937.     short        index = theIndex;
  938.     
  939.     if (index<0)
  940.         index = CountWindows()+index+1;
  941.         
  942.     theWindow = GetWindowPtrOfNthWindow(index);
  943.     if (theWindow)
  944.     {    
  945.         // we are making a possibly dangerous assumption: that all windows are ours!
  946.         *theResultObj = (TScriptableObject*)(((WindowPeek)theWindow)->refCon);
  947.         if (*theResultObj != NULL)
  948.             err = 0;
  949.     }
  950.     
  951.     return err;
  952. }
  953.  
  954.  
  955.  
  956.  
  957. OSErr TSimpliFace::GetTargetObjectSpecifier  (EventRecord& theEvent, AEDesc *result)
  958. {
  959.     WindowPtr    theWindow = FrontWindow();
  960.     
  961.     if (theEvent.what == mouseDown)
  962.         FindWindow(theEvent.where, &theWindow);
  963.             
  964.     if (theWindow)
  965.     {    
  966.         SetPort(theWindow);
  967.         // we are making a possibly dangerous assumption: that all windows are ours!
  968.         TWindowObj    *aWindowObj = (TWindowObj*)(((WindowPeek)theWindow)->refCon);
  969.         if (aWindowObj)
  970.             return aWindowObj->GetTargetObjectSpecifier(theEvent, result);
  971.     }
  972.     else
  973.     {
  974.         OSErr         err = 0;
  975.         AEDesc        containerDesc, newContainerDesc;
  976.         
  977.         err = MakeNullDesc(&containerDesc);
  978.         
  979.         if (!err)
  980.         {
  981.             CStr255        progName;
  982.             AEDesc        nameDesc;
  983.             
  984.             GetCurrAppName(progName);
  985.             err = MakeNameDesc(progName, &nameDesc);
  986.             if (!err)
  987.             {
  988.                 err = CreateObjSpecifier(cApplication, &containerDesc, formName, 
  989.                                          &nameDesc, true, &newContainerDesc);
  990.                 containerDesc = newContainerDesc;
  991.             }
  992.         }
  993.         *result = containerDesc;
  994.         return err;
  995.     }
  996. }    
  997.